package com.ikingtech.datav.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ikingtech.datav.api.ComponentApi;
import com.ikingtech.datav.enums.ComponentTypeEnum;
import com.ikingtech.datav.model.entity.ComponentDO;
import com.ikingtech.datav.model.request.ComponentDTO;
import com.ikingtech.datav.model.request.ComponentSearchDTO;
import com.ikingtech.datav.model.result.ComponentVO;
import com.ikingtech.datav.service.ComponentService;
import com.ikingtech.datav.service.TemplateComponentService;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 组件表(ComponentDO)控制层
 *
 * @author fucb
 * @since 2024-02-22 09:28:34
 */
@RequiredArgsConstructor
@ApiController(value = "/component", name = "可视化大屏-组件管理", description = "可视化大屏-组件管理")
public class ComponentController implements ComponentApi {

    private final ComponentService componentService;

    private final TemplateComponentService templateComponentService;

    /**
     * 查询-个人收藏和公共收藏的组件
     *
     * @return 查询结果
     */
    @Override
    public R<List<ComponentVO>> adminComComponentList() {
        List<ComponentDO> list = componentService.lambdaQuery()
                .eq(ComponentDO::getComponentType, ComponentTypeEnum.COLLECTED.name())
                .and(q -> q.eq(ComponentDO::getIsPublic, 1).or().eq(ComponentDO::getCreateBy, Me.id()))
                .list();
        return R.ok(componentService.convertBatchVO(list));
    }

    /**
     * 分页查询
     *
     * @param param 筛选条件
     * @return 查询结果
     */
    @Override
    public R<List<ComponentVO>> selectByPage(@RequestBody ComponentSearchDTO param) {
        LambdaQueryWrapper<ComponentDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ComponentDO::getComponentType, ComponentTypeEnum.COLLECTED.name());
        if (param.getIsPublic() == null) {
            queryWrapper.and(q -> q.eq(ComponentDO::getIsPublic, 1).or().eq(ComponentDO::getCreateBy, Me.id()));
        } else {
            queryWrapper.eq(ComponentDO::getIsPublic, param.getIsPublic());
            if (param.getIsPublic() == 0) {
                queryWrapper.eq(ComponentDO::getCreateBy, Me.id());
            }
        }
        queryWrapper.like(CharSequenceUtil.isNotBlank(param.getAlias()), ComponentDO::getAlias, param.getAlias());
        Page<ComponentDO> page = componentService.page(new Page<>(param.getPage(), param.getRows()), queryWrapper);
        PageResult<ComponentVO> pageResult = PageResult.build(page.getPages(), page.getTotal(), componentService.convertBatchVO(page.getRecords()));
        return R.ok(pageResult);
    }

    /**
     * 查询详情
     *
     * @param id 主键
     * @return 单条数据
     */
    @Override
    public R<ComponentVO> getInfo(@RequestParam("id") String id) {
        return R.ok(this.componentService.getInfo(id));
    }

    /**
     * 新增
     *
     * @param param 实体
     * @return 新增结果
     */
    @Override
    public R<?> add(@RequestBody ComponentDTO param) {
        if (CharSequenceUtil.isBlank(param.getId())) {
            param.setId(IdUtil.simpleUUID());
        }
        this.componentService.add(param);
        Map<String, String> map = new HashMap<>(1);
        map.put("id", param.getId());
        return R.ok(map);
    }

    /**
     * 新增
     *
     * @param param 实体
     * @return 新增结果
     */
    @Override
    public R<?> add(@RequestBody List<ComponentDTO> param) {
        List<ComponentDO> collect = param.stream().map(this.componentService::extracted).collect(Collectors.toList());
        this.componentService.saveBatch(collect);
        return R.ok();
    }

    /**
     * 编辑
     *
     * @param param 实体
     * @return 编辑结果
     */
    @Override
    public R<String> edit(@RequestBody ComponentDTO param) {
        this.componentService.edit(param);
        return R.ok();
    }

    /**
     * 删除
     *
     * @param list 主键
     * @return 删除是否成功
     */
    @Override
    public R<String> delete(@RequestBody List<String> list) {
        // 删除所有的子组件
        this.componentService.iterativeDeletionComponent(list);
        return R.ok();
    }

    /**
     * 获取组件列表
     * @param screenId 大屏ID
     * @param model    是否子屏
     * @return 组件列表
     */
    @Override
    public R<List<ComponentVO>> comS(@RequestParam String screenId, @RequestParam(value = "model", required = false) Boolean model) {
        if (Boolean.TRUE.equals(model)) {
            return R.ok(componentService.convertBatchVO(BeanUtil.copyToList(templateComponentService.getComponent(screenId), ComponentDO.class)));
        }
        return R.ok(componentService.convertBatchVO(this.componentService.getListByScreenId(screenId)));
    }

    @Override
    public R<?> updates(@RequestBody List<ComponentDTO> componentDTOList) {
        if (componentDTOList.isEmpty()) {
            return R.ok();
        }
        List<ComponentDO> collect = componentDTOList.stream().map(componentService::extracted).collect(Collectors.toList());
        componentService.saveOrUpdateBatch(collect);
        return R.ok();
    }

    @Override
    public R<?> deleteByScreen(@RequestBody ComponentDTO param) {
        componentService.removeByScreenId(param.getId());
        return R.ok();
    }

    @Override
    public R<?> collection(@RequestBody ComponentDTO param) {
        param.setId(IdUtil.simpleUUID());
        ComponentDO extracted = this.componentService.extracted(param);
        extracted.setCreateBy(Me.id());
        extracted.setComponentType(ComponentTypeEnum.COLLECTED.name());
        extracted.setIsPublic(Me.isAdmin() ? 1 : 0);
        this.componentService.save(extracted);
        return R.ok();
    }

    @Override
    public R<?> deleteCollection(@RequestBody ComponentDTO dto) {
        this.componentService.removeBatchByIds(dto.getIds());
        return R.ok();
    }

}

